core: Rework object iteration API to be GFile based and pass more data
authorColin Walters <walters@verbum.org>
Fri, 18 Nov 2011 20:21:32 +0000 (15:21 -0500)
committerColin Walters <walters@verbum.org>
Fri, 18 Nov 2011 20:21:32 +0000 (15:21 -0500)
It makes more sense to have e.g. the details of .packfile naming
inside the repo, and pass the expected checksum and type.

src/libostree/ostree-repo.c
src/libostree/ostree-repo.h
src/ostree/ot-builtin-fsck.c

index 1a1f10b21fafba354d4015f33b300252f15b26ff..35073abb63358b509a67d9199265d34db717ebce 100644 (file)
@@ -1524,9 +1524,9 @@ ostree_repo_commit_from_filelist_fd (OstreeRepo *self,
 }
 
 static gboolean
-iter_object_dir (OstreeRepo   *self,
-                 GFile          *dir,
-                 OstreeRepoObjectIter  callback,
+iter_object_dir (OstreeRepo             *self,
+                 GFile                  *dir,
+                 OstreeRepoObjectIter    callback,
                  gpointer                user_data,
                  GError                **error)
 {
@@ -1534,9 +1534,9 @@ iter_object_dir (OstreeRepo   *self,
   GError *temp_error = NULL;
   GFileEnumerator *enumerator = NULL;
   GFileInfo *file_info = NULL;
-  const char *dirpath = NULL;
+  const char *dirname = NULL;
 
-  dirpath = ot_gfile_get_path_cached (dir);
+  dirname = ot_gfile_get_basename_cached (dir);
 
   enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, 
                                           G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
@@ -1549,31 +1549,44 @@ iter_object_dir (OstreeRepo   *self,
     {
       const char *name;
       guint32 type;
+      char *dot;
+      GFile *child;
+      GString *checksum = NULL;
+      OstreeObjectType objtype;
+
       name = g_file_info_get_attribute_byte_string (file_info, "standard::name"); 
       type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
+
+      if (type == G_FILE_TYPE_DIRECTORY)
+        goto loop_out;
       
-      if (type != G_FILE_TYPE_DIRECTORY
-          && (g_str_has_suffix (name, ".meta")
-              || g_str_has_suffix (name, ".file")
-              || g_str_has_suffix (name, ".packfile")))
-        {
-          char *dot;
-          char *path;
-          
-          dot = strrchr (name, '.');
-          g_assert (dot);
+      if (g_str_has_suffix (name, ".meta"))
+        objtype = OSTREE_OBJECT_TYPE_META;
+      else if (g_str_has_suffix (name, ".file")
+               || g_str_has_suffix (name, ".packfile"))
+        objtype = OSTREE_OBJECT_TYPE_FILE;
+      else
+        goto loop_out;
           
-          if ((dot - name) == 62)
-            {
-              path = g_build_filename (dirpath, name, NULL);
-              callback (self, path, file_info, user_data);
-              g_free (path);
-            }
-        }
+      dot = strrchr (name, '.');
+      g_assert (dot);
 
-      g_object_unref (file_info);
+      if ((dot - name) != 62)
+        goto loop_out;
+      
+      checksum = g_string_new (dirname);
+      g_string_append_len (checksum, name, 62);
+      
+      child = g_file_get_child (dir, name);
+      callback (self, checksum->str, objtype, child, file_info, user_data);
+      
+    loop_out:
+      if (checksum)
+        g_string_free (checksum, TRUE);
+      g_clear_object (&file_info);
+      g_clear_object (&child);
     }
-  if (file_info == NULL && temp_error != NULL)
+  if (temp_error != NULL)
     {
       g_propagate_error (error, temp_error);
       goto out;
@@ -1583,14 +1596,15 @@ iter_object_dir (OstreeRepo   *self,
 
   ret = TRUE;
  out:
+  g_clear_object (&file_info);
   return ret;
 }
 
 gboolean
 ostree_repo_iter_objects (OstreeRepo  *self,
-                            OstreeRepoObjectIter callback,
-                            gpointer       user_data,
-                            GError        **error)
+                          OstreeRepoObjectIter callback,
+                          gpointer       user_data,
+                          GError        **error)
 {
   OstreeRepoPrivate *priv = GET_PRIVATE (self);
   GFile *objectdir = NULL;
index 7f6e27d89dde74846fa079e1f0b34d3cdb45e1b0..1b6948da210b33352f90288e280ca8ff4ae9f048 100644 (file)
@@ -157,13 +157,17 @@ gboolean      ostree_repo_diff (OstreeRepo     *self,
                                 GCancellable   *cancellable,
                                 GError        **error);
 
-typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, const char *path,
-                                        GFileInfo *fileinfo, gpointer user_data);
+typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, 
+                                      const char *checksum,
+                                      OstreeObjectType type,
+                                      GFile      *path,
+                                      GFileInfo  *fileinfo,
+                                      gpointer user_data);
 
 gboolean     ostree_repo_iter_objects (OstreeRepo  *self,
-                                         OstreeRepoObjectIter callback,
-                                         gpointer       user_data,
-                                         GError        **error);
+                                       OstreeRepoObjectIter callback,
+                                       gpointer       user_data,
+                                       GError        **error);
 
 G_END_DECLS
 
index f6f0a1139276ca6c468308748800761df7a33d5a..c9593bb5bf6d00d0de28f84b82bd3957bd78459c 100644 (file)
@@ -41,13 +41,12 @@ typedef struct {
 
 static gboolean
 checksum_packed_file (OtFsckData   *data,
-                      const char   *path,
+                      GFile        *file,
                       GChecksum   **out_checksum,
                       GError      **error)
 {
   gboolean ret = FALSE;
   GChecksum *ret_checksum = NULL;
-  GFile *file = NULL;
   char *metadata_buf = NULL;
   GVariant *metadata = NULL;
   GVariant *xattrs = NULL;
@@ -58,8 +57,6 @@ checksum_packed_file (OtFsckData   *data,
   gsize bytes_read;
   char buf[8192];
 
-  file = ot_gfile_new_for_path (path);
-
   in = g_file_read (file, NULL, error);
   if (!in)
     goto out;
@@ -105,7 +102,6 @@ checksum_packed_file (OtFsckData   *data,
   if (ret_checksum)
     g_checksum_free (ret_checksum);
   g_free (metadata_buf);
-  g_clear_object (&file);
   g_clear_object (&in);
   if (metadata)
    g_variant_unref (metadata);
@@ -115,78 +111,55 @@ checksum_packed_file (OtFsckData   *data,
 }
 
 static void
-object_iter_callback (OstreeRepo  *repo,
-                      const char    *path,
+object_iter_callback (OstreeRepo    *repo,
+                      const char    *exp_checksum,
+                      OstreeObjectType objtype,
+                      GFile         *objf,
                       GFileInfo     *file_info,
                       gpointer       user_data)
 {
   OtFsckData *data = user_data;
-  GChecksum *checksum = NULL;
+  const char *path = NULL;
+  GChecksum *real_checksum = NULL;
   GError *error = NULL;
-  char *dirname = NULL;
-  char *checksum_prefix = NULL;
-  char *checksum_string = NULL;
-  char *filename_checksum = NULL;
-  gboolean packed = FALSE;
-  OstreeObjectType objtype;
-  char *dot;
-  GFile *f = NULL;
 
-  f = ot_gfile_new_for_path (path);
+  path = ot_gfile_get_path_cached (objf);
 
   /* nlinks = g_file_info_get_attribute_uint32 (file_info, "unix::nlink");
      if (nlinks < 2 && !quiet)
      g_printerr ("note: floating object: %s\n", path); */
 
-  if (g_str_has_suffix (path, ".meta"))
-    objtype = OSTREE_OBJECT_TYPE_META;
-  else if (g_str_has_suffix (path, ".file"))
-    objtype = OSTREE_OBJECT_TYPE_FILE;
-  else if (g_str_has_suffix (path, ".packfile"))
-    {
-      objtype = OSTREE_OBJECT_TYPE_FILE;
-     packed = TRUE;
-    }
-  else
-    g_assert_not_reached ();
-
-  if (packed && objtype == OSTREE_OBJECT_TYPE_FILE)
+  if (ostree_repo_is_archive (repo)
+      && objtype == OSTREE_OBJECT_TYPE_FILE)
     {
-      if (!checksum_packed_file (data, path, &checksum, &error))
+      if (!g_str_has_suffix (path, ".packfile"))
+        {
+          g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       "Invalid unpacked filename '%s'",
+                       path);
+          goto out;
+        }
+      if (!checksum_packed_file (data, objf, &real_checksum, &error))
         goto out;
     }
   else
     {
-      if (!ostree_checksum_file (f, objtype, &checksum, NULL, &error))
+      if (!ostree_checksum_file (objf, objtype, &real_checksum, NULL, &error))
         goto out;
     }
 
-  filename_checksum = g_strdup (g_file_info_get_name (file_info));
-  dot = strrchr (filename_checksum, '.');
-  g_assert (dot != NULL);
-  *dot = '\0';
-  
-  dirname = g_path_get_dirname (path);
-  checksum_prefix = g_path_get_basename (dirname);
-  checksum_string = g_strconcat (checksum_prefix, filename_checksum, NULL);
-  
-  if (strcmp (checksum_string, g_checksum_get_string (checksum)) != 0)
+  if (strcmp (exp_checksum, g_checksum_get_string (real_checksum)) != 0)
     {
       data->had_error = TRUE;
       g_printerr ("ERROR: corrupted object '%s' expected checksum: %s\n",
-                  path, g_checksum_get_string (checksum));
+                  exp_checksum, g_checksum_get_string (real_checksum));
     }
 
   data->n_objects++;
 
  out:
-  g_clear_object (&f);
-  if (checksum != NULL)
-    g_checksum_free (checksum);
-  g_free (dirname);
-  g_free (checksum_prefix);
-  g_free (checksum_string);
-  g_free (filename_checksum);
+  if (real_checksum != NULL)
+    g_checksum_free (real_checksum);
   if (error != NULL)
     {
       g_printerr ("%s\n", error->message);